package com.oa.modules.approvalsec1.socket;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.oa.common.utils.EncoderClassVo;
import com.oa.common.utils.SpringContextUtils;
import com.oa.modules.approvalsec1.entity.NewsNoticeEntity;
import com.oa.modules.approvalsec1.entity.RoomStoreEntity;
import com.oa.modules.approvalsec1.service.NewsNoticeService;
import com.oa.modules.approvalsec1.service.RoomStoreService;
import com.oa.modules.approvalsec1.service.impl.NewsNoticeServiceImpl;
import com.oa.modules.sys.controller.AbstractController;
import com.oa.modules.sys.entity.SysUserEntity;
import com.oa.modules.sys.service.SysUserRoleService;
import com.oa.modules.sys.service.SysUserService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * WebSocketServer
 *
 * @author zhengkai.blog.csdn.net
 */
@ServerEndpoint(value = "/imserver", encoders = {EncoderClassVo.class})
@Component
@Log4j2
public class WebSocketServer extends AbstractController {

    /**
     * concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
     */
    private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();

    /**
     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    private Session session;
    private static CopyOnWriteArraySet<WebSocketServer> sessions = new CopyOnWriteArraySet<WebSocketServer>();
    /**
     * 接收userId
     */
    private static String userId = "";
    private static WebSocketServer staticTe;

    @PostConstruct
    public void initialize() {
        staticTe = this;
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) throws IOException, InterruptedException {
        System.out.println("建立连接成功");
        this.session = session;
        sessions.add(this);
        session.getBasicRemote().sendText("连接成功");
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        System.out.println("连接关闭");
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
        }
        sessions.remove(this);
    }

    /**
     * 实现服务器主动推送
     */
    public static void sendMessage2(String userId, String message) {
        try {
            WebSocketServer socketServer = webSocketMap.get(userId);
            if(socketServer!=null){
                socketServer.session.getBasicRemote().sendText(message);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("连接错误");
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(Object message) {
        try {
            if (sessions.size() != 0) {
                for (WebSocketServer s : sessions) {
                    if (s != null) {
                        // 判断是否为终端信息。如果是终端信息则查询数据库获取detail
                        s.session.getBasicRemote().sendObject(message);
                        System.out.println("主动推送完成");
                    }
                }
            }
        } catch (IOException | EncodeException e) {
            log.error(e);
            log.error("sendMessageObject推送失败");
        }

    }

    public static void sendMessage3(String userId, String message) {
        try {
            WebSocketServer socketServer = webSocketMap.get(userId);
            if(socketServer!=null){
                HashMap map = new HashMap();
                map.put("path",message);
                map.put("address","");
                Gson gson = new Gson();
                socketServer.session.getBasicRemote().sendText(gson.toJson(map));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 发送自定义消息
     */
    public static void sendInfo2(String address, String pushUserId) throws IOException {
        Map<String, Object> map = new HashMap<>();
        if (webSocketMap.containsKey(pushUserId)) {
            WebSocketServer server = webSocketMap.get(pushUserId);
            map.put("path","");
            map.put("address",address);
            Gson gson = new Gson();
            server.session.getBasicRemote().sendText(gson.toJson(map));
        } else {
            log.error("用户" + pushUserId + ",不在线！");
        }
    }

    /**
     * 发送自定义消息
     */
    public static void sendInfo(List<NewsNoticeEntity> newsNotice) {
        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < newsNotice.size(); i++) {
            if (StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId) && webSocketMap.containsKey(newsNotice.get(i).getPushUserId())) {
                for (String key : webSocketMap.keySet()) {
                    map.clear();
                    map.put("bHandle", newsNotice.get(i).getBHandle());
                    map.put("lHandle", newsNotice.get(i).getLHandle());
                    map.put("dHandle", newsNotice.get(i).getDHandle());
                    webSocketMap.get(key).sendMessage(map);
                }
            } else {
                log.error("用户" + newsNotice.get(i).getPushUserId() + ",不在线！");
            }
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println("接收客户端消息" + message);
        Gson gson = new Gson();
        if (StringUtils.isNotBlank(message)) {
            Map<String, Object> msg = gson.fromJson(message, Map.class);
            if (msg.get("userId") != null) {
                if (webSocketMap.containsKey(msg.get("userId"))) {
                    webSocketMap.remove(msg.get("userId"));
                }
                webSocketMap.put((String) msg.get("userId"), this);

            }
        }
    }
}
